﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Hockey.UILayer.ViewModels
{
    /// <summary>
    /// Library record
    /// </summary>
    public class LibraryRecord
    {
        public string LibraryName
        { get; set; }

        public string Author
        { get; set; }

        public string URL
        { get; set; }
    }

    /// <summary>
    /// Licence file parser - not very robust I must admit
    /// </summary>
    public class LicensesParser
    {

        private string _sLicenceFileName = "licenses.ini";
        private string _sLicenceDir = "AppData";
        private string _sAppPath;

        // file content container
        private string[] _fileContent;
        private int _lContentIndex;

        // license tokens
        private string _sProgramHeader = "Header";
        private string _sLibraryHeader = "Libraries";
        private string _sProgramNameToken = "ProgramName";
        private string _sURLToken = "CodeUrl";
        private string _sLibraryToken = "Library";

        public LicensesParser(string sAppPath)
        {
            _sAppPath = sAppPath;
            LibraryRecords = new List<LibraryRecord>();
        }

        // output resuls
        public string ProgramName
        { get; set; }

        public string ProgramURL
        { get; set; }

        public List<LibraryRecord> LibraryRecords
        { get; set; }

        /// <summary>
        /// The main parsing method
        /// </summary>
        /// <returns></returns>
        public bool Parse()
        {
            // load the file content
            string sPath = Path.Combine(_sAppPath, _sLicenceDir, _sLicenceFileName);
            if (File.Exists(sPath) == false)
                return false;
            _fileContent = File.ReadAllLines(sPath);
            _lContentIndex = 0;

            // parse header
            if (ParseHeader() == false)
                return false;

            // parse libraries
            if (ParseLibraries() == false)
                return false;

            return true;
        }

        /// <summary>
        /// Parse libraries
        /// </summary>
        private bool ParseLibraries()
        {
            // find the header
            if (FindHeader(_sLibraryHeader) == false)
                return false;

            // interate to the end of file
            while (_lContentIndex < _fileContent.Length)
            {
                string s = _fileContent[_lContentIndex];

                // check empty string
                if (string.IsNullOrWhiteSpace(s) == true)
                    break;

                // is it library record?
                if (s.Contains(_sLibraryToken) == true)
                {
                    int index = s.IndexOf('=');
                    if (index >= 0)
                    {
                        s = s.Substring(index + 1);
                        string[] parts = s.Split(';');

                        // create new record
                        if (parts.Length >= 3)
                        {
                            LibraryRecord libRec = new LibraryRecord();
                            libRec.LibraryName = RemoveQuotes(parts[0]);
                            libRec.Author = RemoveQuotes(parts[1]);
                            libRec.URL = RemoveQuotes(parts[2]);

                            LibraryRecords.Add(libRec);
                        }
                    }
                }

                _lContentIndex++;
            }

            return true;
        }

        /// <summary>
        /// Header parsing method
        /// </summary>
        /// <returns></returns>
        private bool ParseHeader()
        {
            if(FindHeader(_sProgramHeader) == false)
                return false;

            // extract values
            ProgramName = RemoveQuotes(GetTokenValue(_sProgramNameToken, _fileContent[_lContentIndex]));
            _lContentIndex++;
            ProgramURL = RemoveQuotes(GetTokenValue(_sURLToken, _fileContent[_lContentIndex]));

            return true;
        }

        /// <summary>
        /// Find the specific header in the license file
        /// Index is increment for the next line
        /// </summary>
        private bool FindHeader(string sHeader)
        {
            sHeader = '[' + sHeader + ']';
            while (_lContentIndex < _fileContent.Length)
            {
                if (_fileContent[_lContentIndex].Contains(sHeader))
                {
                    _lContentIndex++;
                    return true;
                }

                _lContentIndex++;
            }

            return false;
        }

        /// <summary>
        /// Extracts the token value
        /// </summary>
        private string GetTokenValue(string sToken, string sLine)
        {
            if (sLine.Contains(sToken) == false)
                return string.Empty;
            int index = sLine.IndexOf('=');
            if (index < 0)
                return string.Empty;

            string sValue = sLine.Substring(index + 1);
            return sValue;         
        }

        /// <summary>
        /// Removes the quotes from the string value
        /// </summary>
        private string RemoveQuotes(string sValue)
        {
            int index = sValue.IndexOf('"');
            if (index >= 0)
                sValue = sValue.Substring(index + 1);
            index = sValue.IndexOf('"');
            if(index >= 0)
                sValue = sValue.Substring(0, index);
            return sValue;                                   
        } 
    }
}
